/*
 * Copyright 2010 WithOne Co. Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.co.withone.osgi.gadget.calendar;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;

public class CalendarView extends JFrame {

    public CalendarView() {
        super(Activator.RB.getString("view.title"));
        initComponents();
    }

    private void initComponents() {

        final CalendarInfo info = new CalendarInfo();
        Calendar cal = Calendar.getInstance();
        info.year = cal.get(Calendar.YEAR);
        info.month = cal.get(Calendar.MONTH) + 1;
        info.today = cal.get(Calendar.DAY_OF_MONTH);
        info.setCalendar();

        final JLabel backYear = new JLabel("<", SwingConstants.CENTER);
        backYear.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                info.year--;

                info.setCalendar();
            }
        });
        final JLabel nextYear = new JLabel(">", SwingConstants.CENTER);
        nextYear.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                info.year++;

                info.setCalendar();
            }
        });

        final JLabel backMonth = new JLabel("<", SwingConstants.CENTER);
        backMonth.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                info.month--;
                if (info.month < 1) {
                    info.month = 12;
                    info.year--;
                }

                info.setCalendar();
            }
        });
        final JLabel nextMonth = new JLabel(">", SwingConstants.CENTER);
        nextMonth.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                info.month++;
                if (info.month > 12) {
                    info.month = 1;
                    info.year++;
                }

                info.setCalendar();
            }
        });

        final GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);

        {
            SequentialGroup sg = layout.createSequentialGroup();
            ParallelGroup pg = layout.createParallelGroup();

            {
                SequentialGroup sg2 = layout.createSequentialGroup();
                sg2.addComponent(backYear, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(5);
                sg2.addComponent(info.yearLabel, GroupLayout.PREFERRED_SIZE, 40, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(5);
                sg2.addComponent(nextYear, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(15);
                sg2.addComponent(backMonth, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(5);
                sg2.addComponent(info.monthLabel, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(5);
                sg2.addComponent(nextMonth, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE);
                sg2.addGap(5);

                pg.addGroup(sg2);
            }
            {
                SequentialGroup sg1 = layout.createSequentialGroup();
                for (int x = 0; x < 7; x++) {
                    ParallelGroup pg2 = layout.createParallelGroup();
                    for (int y = 0; y < 7; y++) {
                        pg2.addComponent(info.calendar[y][x], GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE);
                    }
                    sg1.addGroup(pg2);

                }
                pg.addGroup(sg1);
            }

            sg.addGroup(pg);

            layout.setHorizontalGroup(sg);
        }
        {
            SequentialGroup sg = layout.createSequentialGroup();
            ParallelGroup pg = layout.createParallelGroup();
            pg.addComponent(backYear);
            pg.addComponent(info.yearLabel);
            pg.addComponent(nextYear);
            pg.addComponent(backMonth);
            pg.addComponent(info.monthLabel);
            pg.addComponent(nextMonth);
            sg.addGroup(pg);
            for (int y = 0; y < 7; y++) {
                pg = layout.createParallelGroup();
                for (int x = 0; x < 7; x++) {
                    pg.addComponent(info.calendar[y][x]);
                }
                sg.addGroup(pg);
            }
            layout.setVerticalGroup(sg);
        }

        pack();
    }

    class CalendarInfo {
        int year;
        int month;
        int today;
        JLabel yearLabel;
        JLabel monthLabel;
        JLabel[][] calendar;

        private CalendarInfo() {
            this.yearLabel = new JLabel("", SwingConstants.CENTER);
            this.monthLabel = new JLabel("", SwingConstants.CENTER);
            this.calendar = new JLabel[7][7];

            for (int y = 1; y < 7; y++) {
                for (int x = 0; x < 7; x++) {
                    this.calendar[y][x] = new JLabel("", SwingConstants.CENTER);
                }
            }

            this.calendar[0][0] = new JLabel("Sun", SwingConstants.CENTER);
            this.calendar[0][1] = new JLabel("Mon", SwingConstants.CENTER);
            this.calendar[0][2] = new JLabel("Tue", SwingConstants.CENTER);
            this.calendar[0][3] = new JLabel("Wed", SwingConstants.CENTER);
            this.calendar[0][4] = new JLabel("Thu", SwingConstants.CENTER);
            this.calendar[0][5] = new JLabel("Fri", SwingConstants.CENTER);
            this.calendar[0][6] = new JLabel("Sat", SwingConstants.CENTER);

            for (int y = 0; y < 7; y++) {
                for (int x = 0; x < 7; x++) {
                    this.calendar[y][x].setFont(new Font(Font.DIALOG, Font.BOLD, 9));
                }
            }

            for (int y = 0; y < 7; y++) {
                this.calendar[y][0].setForeground(Color.RED);
                this.calendar[y][6].setForeground(Color.BLUE);
            }
        }

        public void setCalendar() {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.YEAR, this.year);
            cal.set(Calendar.MONTH, this.month - 1);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

            int day = 1;
            for (int y = 1; y < 7; y++) {
                for (int x = 0; x < 7; x++) {
                    if (dayOfWeek > 1) {
                        dayOfWeek--;
                        this.calendar[y][x].setText("");
                        continue;
                    }
                    if (day > lastDay) {
                        this.calendar[y][x].setText("");
                    } else {
                        this.calendar[y][x].setText(String.valueOf(day));
                        day++;
                    }
                }
            }
            this.yearLabel.setText(String.valueOf(this.year));
            this.monthLabel.setText(String.valueOf(this.month));
        }
    }
}
